package edu.ucsc.mit2008.swan.editor.core;

import java.util.Map;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException;

/**
 * Preferences manage to manage swan editor preferences.
 * 
 * 
 * @author Thushara Sanjeewa Ramasinghe
 *
 */
public class SwanPreferenceManager {
	private static String dot_ = "._"; //$NON-NLS-1$
	private static String _key = "_key"; //$NON-NLS-1$
	private static String _value = "_value"; //$NON-NLS-1$

	private IEclipsePreferences preferences;

	private SwanPreferenceManager instance;

	private SwanPreferenceManager() {
	}

	public SwanPreferenceManager getInstance() {
		if (instance == null)
			instance = new SwanPreferenceManager();
		return instance;
	}

	/** Convenience method to get the preferences */
	protected IEclipsePreferences getPreferences() {
		if (preferences == null)
			preferences = new InstanceScope().getNode(SwanCorePlugin.PLUGIN_ID);
		return preferences;
	}

	/**
	 * Convenience method to save the preferences
	 * 
	 * @throws BackingStoreException
	 */
	protected void savePreferences() throws BackingStoreException {
		preferences.flush();
	}

	/**
	 * Method that can be used to retrieve an exploded map stored via setMap
	 * 
	 * @param key
	 */
	protected void loadMap(String key, Map<String, String> map) {
		int idx = 0;
		while (true) {
			if (getPreferences().get(key + dot_ + idx + _key, null) == null
					|| getPreferences().get(key + dot_ + idx + _key, null)
							.length() == 0) {
				return;
			}

			map.put(getPreferences().get(key + dot_ + idx + _key, null),
					getPreferences().get(key + dot_ + idx + _value, null));
			idx++;
		}
	}

	/**
	 * Saves a map in exploded form under the specified key. Any existing
	 * exploded entries are removed. Note, nulls will be replaced with empty
	 * strings!
	 * 
	 * @param key
	 * @param map
	 */
	protected void storeMap(String key, Map<String, String> map) {
		// Remove old values
		int idx = 0;
		while (true) {
			if (getPreferences().get(key + dot_ + idx + _key, null) == null
					|| getPreferences().get(key + dot_ + idx + _key, null)
							.length() == 0) {
				break;
			}

			getPreferences().put(key + dot_ + idx + _key, null);
			getPreferences().put(key + dot_ + idx + _value, null);
			idx++;
		}

		// Add new values
		idx = 0;
		for (Map.Entry<String, String> entry : map.entrySet()) {
			getPreferences().put(key + dot_ + idx + _key,
					entry.getKey() != null ? entry.getKey() : ""); //$NON-NLS-1$
			getPreferences().put(key + dot_ + idx + _value,
					entry.getValue() != null ? entry.getValue() : ""); //$NON-NLS-1$
			idx++;
		}
	}
}
